#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <librtmp/rtmp.h>
#include <portaudio.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/tcp.h>
#include "g711.h"
#include <emscripten/emscripten.h>

#define SAMPLE_RATE 8000
#define NUM_CHANNELS 1
#define SAMPLE_FORMAT paInt16
#define FRAME_SIZE 1024
//#define RTMP_URL "rtmp://139.159.149.7/live/liws"
#define RTMP_URL "rtmp://139.159.149.4/live/liws"  // 替换为你的RTMP服务器地址和流名

RTMP* rtmp;

static int audioCallback(const void *inputBuffer, void *outputBuffer,
                         unsigned long framesPerBuffer,
                         const PaStreamCallbackTimeInfo* timeInfo,
                         PaStreamCallbackFlags statusFlags,
                         void *userData)
{
    int size = framesPerBuffer * NUM_CHANNELS; // * sizeof(short);
    int totalSize = size + 1;
    RTMPPacket packet;
    RTMPPacket_Reset(&packet);
    RTMPPacket_Alloc(&packet, totalSize);

    packet.m_packetType = RTMP_PACKET_TYPE_AUDIO;
    packet.m_nBodySize = totalSize;

    /*
     * 消息通道，对应rtmp报文头中的cs_id
     * 0x02 控制流通道
     * 0x03 命令信道
     * 0x05 数据流通道
     * 0x06 视频信道
     * 0x07 音频信道
     */
    packet.m_nChannel = 0x07;//0x05;
    packet.m_headerType = RTMP_PACKET_SIZE_LARGE;
    packet.m_nInfoField2 = rtmp->m_stream_id;

    short *samples = (short *)inputBuffer;
    unsigned char *resData = malloc(totalSize);
    resData[0] = 0x76;//0x06
    unsigned char *g711aData = encodeG711a(samples, size);
    for (int i = 0; i < size; ++i) {
        resData[i+1] = g711aData[i];
    }

//    memcpy(packet.m_body, inputBuffer, packet.m_nBodySize);
    memcpy(packet.m_body, resData, packet.m_nBodySize);

    if (!RTMP_SendPacket(rtmp, &packet, 0)) {
        RTMPPacket_Free(&packet);
        fprintf(stderr, "Failed to send RTMP packet\n");
        return paAbort;
    }

    RTMPPacket_Free(&packet);
    return paContinue;
}

int EMSCRIPTEN_KEEPALIVE startAudio() {
    Pa_Initialize();
    PaStream* stream;
    PaError err;

    // 打开默认输入设备
    PaStreamParameters inputParameters;
    inputParameters.device = Pa_GetDefaultInputDevice();
    if (inputParameters.device == paNoDevice) {
        fprintf(stderr, "Error: No default input device.\n");
        Pa_Terminate();
        return -1;
    }
    inputParameters.channelCount = NUM_CHANNELS;
    inputParameters.sampleFormat = SAMPLE_FORMAT;
    inputParameters.suggestedLatency = Pa_GetDeviceInfo(inputParameters.device)->defaultLowInputLatency;
    inputParameters.hostApiSpecificStreamInfo = NULL;


    err = Pa_OpenStream(&stream,
                        &inputParameters,
                        NULL,
                        SAMPLE_RATE,
                        FRAME_SIZE,
                        paClipOff,
                        audioCallback,
                        NULL);
    if (err != paNoError) {
        fprintf(stderr, "Error opening audio stream: %s\n", Pa_GetErrorText(err));
        Pa_Terminate();
        return -1;
    }

    // Initialize librtmp and open RTMP connection
    rtmp = RTMP_Alloc();
    RTMP_Init(rtmp);

    RTMP_SetupURL(rtmp, RTMP_URL);

    RTMP_EnableWrite(rtmp);
    int connectFlag = RTMP_Connect(rtmp, 0);
    if(!connectFlag) {
        printf("Rtmp connect failure.\n");
        Pa_Terminate();
        RTMP_Close(rtmp);
        RTMP_Free(rtmp);
        return 1;
    }
    RTMP_ConnectStream(rtmp, 0);

    Pa_StartStream(stream);

    printf("Press Enter to stop...\n");
    getchar();

    // 停止和关闭音频流
    err = Pa_StopStream(stream);
    if (err != paNoError) {
        fprintf(stderr, "Error stopping audio stream: %s\n", Pa_GetErrorText(err));
    }

    err = Pa_CloseStream(stream);
    if (err != paNoError) {
        fprintf(stderr, "Error closing audio stream: %s\n", Pa_GetErrorText(err));
    }
    Pa_Terminate();

    // Close RTMP connection
    RTMP_Close(rtmp);
    RTMP_Free(rtmp);

    return 0;
}


//int main() {
//    Pa_Initialize();
//    PaStream* stream;
//    PaError err;
//
//    // 打开默认输入设备
//    PaStreamParameters inputParameters;
//    inputParameters.device = Pa_GetDefaultInputDevice();
//    if (inputParameters.device == paNoDevice) {
//        fprintf(stderr, "Error: No default input device.\n");
//        Pa_Terminate();
//        return -1;
//    }
//    inputParameters.channelCount = NUM_CHANNELS;
//    inputParameters.sampleFormat = SAMPLE_FORMAT;
//    inputParameters.suggestedLatency = Pa_GetDeviceInfo(inputParameters.device)->defaultLowInputLatency;
//    inputParameters.hostApiSpecificStreamInfo = NULL;
//
//
//    err = Pa_OpenStream(&stream,
//                       &inputParameters,
//                       NULL,
//                       SAMPLE_RATE,
//                       FRAME_SIZE,
//                       paClipOff,
//                       audioCallback,
//                       NULL);
//    if (err != paNoError) {
//        fprintf(stderr, "Error opening audio stream: %s\n", Pa_GetErrorText(err));
//        Pa_Terminate();
//        return -1;
//    }
//
//    // Initialize librtmp and open RTMP connection
//
//    rtmp = RTMP_Alloc();
//    RTMP_Init(rtmp);
//
//    RTMP_SetupURL(rtmp, RTMP_URL);
////// 创建套接字
////    int sockfd = socket(AF_INET, SOCK_STREAM, 6);
////    if (sockfd < 0) {
////        perror("Failed to create socket");
////        RTMP_Free(rtmp);
////        return 1;
////    }
////    struct timeval timeout;
////    timeout.tv_sec = 2; // 10 秒
////    timeout.tv_usec = 0;
////
////    if (setsockopt(sockfd, SOL_SOCKET, SO_SNDTIMEO, &timeout, sizeof(timeout)) < 0) {
////        fprintf(stderr, "Failed to set send timeout\n");
////        RTMP_Free(rtmp);
////        return 1;
////    }
////
////    // 设置套接字
////    rtmp->Link.timeout = 3;
//
//    RTMP_EnableWrite(rtmp);
//    int connectFlag = RTMP_Connect(rtmp, 0);
//    if(!connectFlag) {
//        printf("Rtmp connect failure.\n");
//        Pa_Terminate();
//        RTMP_Close(rtmp);
//        RTMP_Free(rtmp);
//        return 1;
//    }
//    RTMP_ConnectStream(rtmp, 0);
//
//    Pa_StartStream(stream);
//
//    printf("Press Enter to stop...\n");
//    getchar();
//
//    // 停止和关闭音频流
//    err = Pa_StopStream(stream);
//    if (err != paNoError) {
//        fprintf(stderr, "Error stopping audio stream: %s\n", Pa_GetErrorText(err));
//    }
//
//    err = Pa_CloseStream(stream);
//    if (err != paNoError) {
//        fprintf(stderr, "Error closing audio stream: %s\n", Pa_GetErrorText(err));
//    }
//    Pa_Terminate();
//
//    // Close RTMP connection
//    RTMP_Close(rtmp);
//    RTMP_Free(rtmp);
//
//    return 0;
//}
